﻿using System;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Threading;

namespace WeiboPlus.Models
{
    public class NotificationObject : INotifyPropertyChanging, INotifyPropertyChanged
    {
        // Fields
        private PropertyChangingEventHandler _propertyChanging;
        private PropertyChangedEventHandler _propertyChanged;

        public event PropertyChangingEventHandler PropertyChanging
        {
            add
            {
                PropertyChangingEventHandler handler2;
                PropertyChangingEventHandler propertyChanged = _propertyChanging;
                do
                {
                    handler2 = propertyChanged;
                    PropertyChangingEventHandler handler3 = (PropertyChangingEventHandler)Delegate.Combine((Delegate)handler2, (Delegate)value);
                    propertyChanged = Interlocked.CompareExchange<PropertyChangingEventHandler>(ref _propertyChanging, handler3, handler2);
                }
                while (propertyChanged != handler2);
            }
            remove
            {
                PropertyChangingEventHandler handler2;
                PropertyChangingEventHandler propertyChanged = _propertyChanging;
                do
                {
                    handler2 = propertyChanged;
                    PropertyChangingEventHandler handler3 = (PropertyChangingEventHandler)Delegate.Remove((Delegate)handler2, (Delegate)value);
                    propertyChanged = Interlocked.CompareExchange<PropertyChangingEventHandler>(ref _propertyChanging, handler3, handler2);
                }
                while (propertyChanged != handler2);
            }
        }

        // Events
        public event PropertyChangedEventHandler PropertyChanged
        {
            add
            {
                PropertyChangedEventHandler handler2;
                PropertyChangedEventHandler propertyChanged = _propertyChanged;
                do
                {
                    handler2 = propertyChanged;
                    PropertyChangedEventHandler handler3 = (PropertyChangedEventHandler)Delegate.Combine((Delegate)handler2, (Delegate)value);
                    propertyChanged = Interlocked.CompareExchange<PropertyChangedEventHandler>(ref _propertyChanged, handler3, handler2);
                }
                while (propertyChanged != handler2);
            }
            remove
            {
                PropertyChangedEventHandler handler2;
                PropertyChangedEventHandler propertyChanged = _propertyChanged;
                do
                {
                    handler2 = propertyChanged;
                    PropertyChangedEventHandler handler3 = (PropertyChangedEventHandler)Delegate.Remove((Delegate)handler2, (Delegate)value);
                    propertyChanged = Interlocked.CompareExchange<PropertyChangedEventHandler>(ref _propertyChanged, handler3, handler2);
                }
                while (propertyChanged != handler2);
            }
        }

        // Methods
        public NotificationObject()
        {
        }

        protected void RaisePropertyChanging(params string[] propertyNames)
        {
            if (propertyNames == null)
            {
                throw new ArgumentNullException("propertyNames");
            }
            foreach (string str in propertyNames)
            {
                this.RaisePropertyChanging(str);
            }
        }

        protected void RaisePropertyChanging<T>(Expression<Func<T>> propertyExpression)
        {
            string propertyName = PropertySupport.ExtractPropertyName<T>(propertyExpression);
            this.RaisePropertyChanging(propertyName);
        }

        protected virtual void RaisePropertyChanging(string propertyName)
        {
            PropertyChangingEventHandler propertyChanging = _propertyChanging;

            if (propertyChanging != null)
            {
                propertyChanging(this, new PropertyChangingEventArgs(propertyName));
            }
        }

        protected void RaisePropertyChanged(params string[] propertyNames)
        {
            if (propertyNames == null)
            {
                throw new ArgumentNullException("propertyNames");
            }
            foreach (string str in propertyNames)
            {
                this.RaisePropertyChanged(str);
            }
        }

        protected void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpression)
        {
            string propertyName = PropertySupport.ExtractPropertyName<T>(propertyExpression);
            this.RaisePropertyChanged(propertyName);
        }

        protected virtual void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler propertyChanged = _propertyChanged;
            if (propertyChanged != null)
            {
                propertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}
